#include "log.h"
#include <stdio.h>
namespace sylar{
const char* LogLevel::ToString(LogLevel::Level Level) {
    switch (Level) {
/// @brief 定义宏减少重复代码
#define XX(name)    \
    case LogLevel::name:    \
        return #name;   \
        break;
    
    XX(DEBUG);
    XX(INFO);
    XX(WARN);
    XX(ERROR);
    XX(FATAL);
#undef XX    
    default:
        return "UNKNOW";
    }   
    return "UNKNOW";
}

LogLevel::Level LogLevel::FromString(const std::string& str) {
#define XX(level, v)    \
    if(str == #v) { \
        return LogLevel::level; \
    }
    
    XX(DEBUG, debug);
    XX(INFO, info);
    XX(WARN, warn);
    XX(ERROR, error);
    XX(FATAL, fatal);

    XX(DEBUG, DEBUG);
    XX(INFO, INFO);
    XX(WARN, WARN);
    XX(ERROR, ERROR);
    XX(FATAL, FATAL);
    return LogLevel::UNKNOW;
#undef XX
}

LogEvent::LogEvent(std::shared_ptr<Logger> logger, LogLevel::Level level, const char* file, int32_t line, uint32_t elapse,
    uint32_t thread_id, uint32_t coroutine_id, uint64_t time, const std::string& thread_name)
    :m_file(file), m_line(line), m_elapse(elapse)
    ,m_threadId(thread_id), m_coroutineId(coroutine_id)
    ,m_time(time), m_threadName(thread_name)
    , m_logger(logger), m_level(level)   
{
}

void LogEvent::format(const char* fmt, ...){
    va_list al;
    va_start(al, fmt);
    format(fmt, al);
    va_end(al);
}

void LogEvent::format(const char* fmt, va_list al){
    char* buf = nullptr;
    //自动分配足够的内存存储格式化后的字符串
    int len = __vasprintf(&buf, fmt, al);
    if(len != -1){
        m_ss << std::string(buf, len);
        free(buf);
    }
}

int  __vasprintf(char** buf, const char* fmt, va_list args)
{
    va_list args_copy;
    va_copy(args_copy, args);

    //计算所需长度
    /// @brief 将格式化输入写入指定长度的字符缓冲区
    /// @param 1：目标缓冲区  
    /// @param 2：缓冲区最大长度 
    /// @param 3：格式化字符串
    /// @param 4: valist
    /// @return 实际写入的字符数
    int len = vsnprintf(nullptr, 0, fmt, args_copy);
    va_end(args_copy);

    if(len < 0){
        return -1; // 格式化失败
    }

    //分配内存
    char* buffer = (char*)malloc(len + 1);
    if(!buf){
        return -2;  // 内存不足
    }
    //写入格式化内容
    int len1 = vsnprintf(buffer, len + 1, fmt, args);
    //实际写入字符数为len
    if(len1 != len){
        free(buffer);   // 释放内存
        return -3;  
    }

    *buf = buffer;
    return len;
}

std::stringstream& LogEventWrap::getSS(){
    return m_event->getSS();
}

}


